﻿#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
//1.set和multiset头文件；
#include <set>
#include <string>

/*
set构造函数
set<T> st;//set默认构造函数
mulitset<T> mst; //multiset默认构造函数
set(const set& st);//拷贝构造函数

set赋值操作
set& operator=(const set& st);//重载等号操作符
swap(st);//交换两个集合容器

set大小操作
size();//返回容器中元素的数目
empty();//判断容器是否为空

set插入和删除操作
insert(elem);//在容器中插入元素
clear();//清除所有元素
erase(pos);//删除pos迭代器所指的元素，返回下一个元素的迭代器
erase(beg, end);//删除区间[beg,end)的所有元素 ，返回下一个元素的迭代器
erase(elem);//删除容器中值为elem的元素
*/
/*
set查找操作
find(key);//查找键key是否存在,若存在，返回该键的元素的迭代器；若不存在，返回set.end();
count(key);//查找键key的元素个数
lower_bound(keyElem);//返回第一个key>=keyElem元素的迭代器
upper_bound(keyElem);//返回第一个key>keyElem元素的迭代器
equal_range(keyElem);//返回容器中key与keyElem相等的上下限的两个迭代器
*/
void printSet(set<int>& s)
{
	for (set<int>::iterator it = s.begin(); it != s.end(); ++it)
	{
		cout << *it << " ";
	}
	cout << endl;
}
//13.指定set排序规则，从大到小；仿函数；
class MyCompareSet
{
public:
	//14.重载()；
	bool operator()(int v1, int v2)const
	{
		return v1 > v2;
	}
};
//15.自定义数据类型；
class PersonSet
{
public:
	PersonSet(string name, int age)
	{
		this->m_Name = name;
		this->m_Age = age;
	}

	string m_Name;
	int m_Age;
};
class MyComparePerson
{
public:
	bool operator()(const PersonSet& p1, const PersonSet& p2)const
	{
		//17.降序排列；
		if (p1.m_Age > p2.m_Age)
		{
			return true;
		}
		return false;
	}
};
void testSet()
{
	set<int> s1;

	//2.set是关联式容器，按照key，会自动进行排序，从小到大；
	s1.insert(5);
	s1.insert(1);
	s1.insert(9);
	s1.insert(3);
	s1.insert(7);

	printSet(s1);//1 3 5 7 9

	if (s1.empty())
	{
		cout << "s1为空！" << endl;
	}
	else
	{
		cout << "s1的size=" << s1.size() << endl;//5
	}

	s1.erase(s1.begin());
	printSet(s1);//3 5 7 9
	s1.erase(3);
	printSet(s1);//5 7 9

	//3.对于set，没有value，key就是value；
	set<int>::iterator pos = s1.find(5);
	//4.判断是否找到；
	if (pos != s1.end())
	{
		cout << "找到了，值为：" << *pos << endl;//5
	}
	else
	{
		cout << "未找到！" << endl;
	}

	//5.count(key);//查找键key的元素个数；对set而言，结果为0或者1；
	int num = s1.count(8);//7 --> 8
	cout << "元素7的个数为：" << num << endl;//1 --> 0

	//6.lower_bound(keyElem);//返回第一个key>=keyElem元素的迭代器
	set<int>::iterator it = s1.lower_bound(10);//9 --> 10
	if (it != s1.end())
	{
		cout << "找到了lower_bound(9)的值为：" << *it << endl;//9
	}
	else
	{
		cout << "未找到！" << endl;//未找到
	}

	//7.upper_bound(keyElem);//返回第一个key>keyElem元素的迭代器
	set<int>::iterator itU = s1.upper_bound(9);//7 --> 9
	if (itU != s1.end())
	{
		cout << "找到了upper_bound(7)的值为：" << *itU << endl;//9
	}
	else
	{
		cout << "未找到！" << endl;//未找到
	}

	//8.equal_range(keyElem);//返回容器中key与keyElem相等的上下限的两个迭代器
		//上下限，就是lower_bound和upper_bound
	pair<set<int>::iterator, set<int>::iterator> ret = s1.equal_range(5);
	//9.获取第一个值；
	if (ret.first != s1.end())
	{
		cout << "找到equal_range中lower_bound的值：" << *(ret.first) << endl;//5
	}
	else
	{
		cout << "未找到！" << endl;
	}
	//10.获取第二个值；
	if (ret.second != s1.end())
	{
		cout << "找到equal_range中upper_bound的值：" << *(ret.second) << endl;//7
	}
	else
	{
		cout << "未找到！" << endl;
	}

	//11.set容器，不允许插入重复的键值；
	pair<set<int>::iterator, bool> reti = s1.insert(10);
	if (reti.second)
	{
		cout << "插入成功！" << endl;//插入成功！
	}
	else
	{
		cout << "插入失败！" << endl;
	}
	reti = s1.insert(10);
	if (reti.second)
	{
		cout << "第二次插入成功！" << endl;
	}
	else
	{
		cout << "第二次插入失败！" << endl;//第二次插入失败！
	}
	printSet(s1);//5 7 9 10

	//18.multiset允许插入重复值；
	multiset<int> mul;
	mul.insert(10);
	mul.insert(10);

	//12.set容器排序；从大到小排序，在插入之前就指定排序规则；
		//自定义数据类型，即自定义类MyCompareSet；
	set<int, MyCompareSet> s2;

	s2.insert(5);
	s2.insert(1);
	s2.insert(9);
	s2.insert(3);
	s2.insert(7);

	for (set<int, MyCompareSet>::iterator it = s2.begin(); it != s2.end(); ++it)
	{
		cout << *it << " ";//9 7 5 3 1
	}
	cout << endl;

	set<PersonSet, MyComparePerson> sp;
	PersonSet p1("大娃", 100);
	PersonSet p2("二娃", 90);
	PersonSet p3("六娃", 10);
	PersonSet p4("爷爷", 1000);

	sp.insert(p1);
	sp.insert(p2);
	sp.insert(p3);
	sp.insert(p4);
	//16.插入自定义数据类型，上来就指定好排序规则；
		//显示；
	for (set<PersonSet, MyComparePerson>::iterator it = sp.begin(); it != sp.end(); ++it)
	{
		cout << "姓名：" << (*it).m_Name << " ，年龄：" << it->m_Age << endl;
	}
	/*姓名：爷爷 ，年龄：1000
	姓名：大娃 ，年龄：100
	姓名：二娃 ，年龄：90
	姓名：六娃 ，年龄：10*/
}

//main326：set集合容器
int main326()
{
	testSet();

	system("pause");
	return EXIT_SUCCESS;
}